package com.itfitness.stretchcalendarview.widget.calendarview.widget

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.itfitness.stretchcalendarview.R
import com.itfitness.stretchcalendarview.utils.CalendarUtil
import com.itfitness.stretchcalendarview.widget.calendarview.adapter.TimePeriodCalendarAdapter
import com.itfitness.stretchcalendarview.widget.calendarview.bean.SelectPeriodBean
import com.itfitness.stretchcalendarview.widget.calendarview.bean.TimePeriodCalendarDateBean
import java.util.Calendar

/**
 * 区间日历
 */
class TimePeriodCalendarView: FrameLayout {
    var mSelectYear = 0
    var mSelectMonth = 0
    var mSelectDay = 0
    private lateinit var wgvCalendar:WrapGridView

    private var calendarAdapter: TimePeriodCalendarAdapter? = null

    private var alreadySelectPeriods = ArrayList<SelectPeriodBean>()
    private var currentSelectPeriodBean:SelectPeriodBean? = null
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){
        View.inflate(context, R.layout.view_timeperiodcalendar,this)
        initView()
        initListener()
    }

    private fun initListener() {
        wgvCalendar.setOnTouchListener(object :OnTouchListener{
            override fun onTouch(view: View?, event: MotionEvent?): Boolean {
                val touchPos = getTouchPos(event)
                LogUtils.eTag("日历位置",touchPos[0],touchPos[1],touchPos[2])
                when(event?.action){
                    MotionEvent.ACTION_DOWN->{
                        val isCorrectPos = isCorrectPos(touchPos[2])
                        if(isCorrectPos){
                            calendarAdapter?.data!![touchPos[2]].type = 0
                            currentSelectPeriodBean = SelectPeriodBean()
                            currentSelectPeriodBean?.start = touchPos[2]
                        }else{
                            //位置不对，检测是否点击了结尾的
                            checkIsSelectEnd(touchPos[2])
                            currentSelectPeriodBean?.let {
                                if(currentSelectPeriodBean?.start == currentSelectPeriodBean?.end){
                                    calendarAdapter?.data!![touchPos[2]].type = 0
                                }
                            }
                        }
                        LogUtils.eTag("日历按下",event?.x,event?.y,wgvCalendar?.width,wgvCalendar?.height)
                    }
                    MotionEvent.ACTION_MOVE->{
                        currentSelectPeriodBean?.let {
                            val isCorrectPos = isCorrectPos(touchPos[2])
                            if(isCorrectPos){
                                selectPeriod(touchPos[2])
                            }
                        }
                        LogUtils.eTag("日历移动",event?.x,event?.y,wgvCalendar?.width,wgvCalendar?.height)
                    }
                    MotionEvent.ACTION_UP->{
                        currentSelectPeriodBean?.let {
                            if(touchPos[2] >= calendarAdapter?.data!!.size){
                                touchPos[2] = calendarAdapter?.data!!.size-1
                            }
                            currentSelectPeriodBean?.end = touchPos[2]
                            //判断收尾是否在一个
                            if(currentSelectPeriodBean?.start == currentSelectPeriodBean?.end){
                                calendarAdapter?.data!![touchPos[2]].type = 3
                            }else{
                                calendarAdapter?.data!![touchPos[2]].type = 2
                            }
                            if(!alreadySelectPeriods.contains(currentSelectPeriodBean)){
                                alreadySelectPeriods.add(currentSelectPeriodBean!!)
                            }
                            currentSelectPeriodBean = null
                        }
                        LogUtils.eTag("日历抬起",event?.x,event?.y,wgvCalendar?.width,wgvCalendar?.height)
                    }
                }
                currentSelectPeriodBean?.let {
                    calendarAdapter?.notifyDataSetChanged()
                }
                return true
            }
        })
    }

    /**
     * 检查是否选择了结尾的
     */
    private fun checkIsSelectEnd(pos: Int) {
        for(timePeriod in alreadySelectPeriods){
            if(pos == timePeriod.end){
                currentSelectPeriodBean = timePeriod
                alreadySelectPeriods.remove(timePeriod)
                break
            }
        }
    }

    /**
     * 判断当前点击的是否是正确的位置
     */
    private fun isCorrectPos(pos: Int):Boolean{
        var correctPos = true
        if(pos < getMonthOneDayWeek() - 1 || pos >= calendarAdapter?.data!!.size){
            correctPos = false
            ToastUtils.showShort("请选择正确的位置")
            return correctPos
        }
        for(timePeriod in alreadySelectPeriods){
            if(pos >= timePeriod.start && pos <= timePeriod.end){
                correctPos = false
                if(pos != timePeriod.end){
                    //调整以前位置不提示信息
                    ToastUtils.showShort("选择位置重叠")
                }
                break
            }else{
                correctPos = true
            }
        }
        currentSelectPeriodBean?.let {
            out@for(i in currentSelectPeriodBean?.start!!..pos){
                for(timePeriod in alreadySelectPeriods){
                    if(i >= timePeriod.start && i <= timePeriod.end){
                        correctPos = false
                        ToastUtils.showShort("选择位置重叠")
                        break@out
                    }else{
                        correctPos = true
                    }
                }
            }
        }
        return correctPos
    }

    /**
     * 选择区间
     */
    private fun selectPeriod(inputPos: Int) {
        var pos = inputPos
//        if(pos == currentSelectPeriodBean?.start){
//            return
//        }
        if(pos >= calendarAdapter?.data!!.size){
            pos = calendarAdapter?.data!!.size-1
        }
        for(i in currentSelectPeriodBean?.start!! + 1 until pos){
            val date = calendarAdapter?.data!![i]
            if(date.day != 0){
                date.type = 1
            }
        }
        for(i in pos + 1 until calendarAdapter?.data!!.size){
            var reset = true
            for(timePeriod in alreadySelectPeriods){
                if(i >= timePeriod.start && i <= timePeriod.end){
                    reset = false
                    break
                }else{
                    reset = true
                }
            }
            if (reset){
                val date = calendarAdapter?.data!![i]
                if(date.day != 0){
                    date.type = -1
                }
            }
        }
        //往后移动超过了最初位置
        if(pos < currentSelectPeriodBean?.start!!){
            currentSelectPeriodBean?.start = pos
            calendarAdapter?.data!![pos].type = 0
        }else{
            calendarAdapter?.data!![pos].type = 2
        }
    }

    private fun getTouchPos(event: MotionEvent?):Array<Int>{
        val rowNum: Int = (calendarAdapter?.count!! + wgvCalendar.getNumColumns() as Int) / wgvCalendar.getNumColumns() as Int
        LogUtils.eTag("日历行数",rowNum)
        val itemWidth = wgvCalendar.width / 7
        val itemHeight = wgvCalendar.height / rowNum
        var posColumn = -1
        for (i in 1..7){
            if(event?.x!! >= itemWidth * i){
                continue
            }else{
                posColumn = i
                break
            }
        }
        var posRow = -1
        for (i in 1..7){
            if(event?.y!! >= itemHeight * i){
                continue
            }else{
                posRow = i
                break
            }
        }

        val itemPos = posRow * 7 - (7 - posColumn) - 1

        return arrayOf(
            posColumn,posRow,itemPos
        )
    }

    private fun initView() {
        wgvCalendar = findViewById(R.id.wgvCalendar)
    }

    fun initData(year:Int,month: Int,day:Int){
        mSelectYear = year
        mSelectMonth = month - 1
        mSelectDay = day
        stretch()
    }

    fun stretch(){
        val data = ArrayList<TimePeriodCalendarDateBean>()
        //获取第一天是星期几然后计算出需要填充的空白数据
        repeat(getMonthOneDayWeek() - 1){
            //填充空白的
            data.add(TimePeriodCalendarDateBean(0,0,0,"","",-1))
        }
        //填充日期数据
        repeat(getMonthMaxDay()){
            val lunar = CalendarUtil.solarToLunar(mSelectYear,mSelectMonth + 1,it + 1)
            val festival = CalendarUtil.solarToFestival(mSelectYear,mSelectMonth + 1,it + 1)
            data.add(TimePeriodCalendarDateBean(mSelectYear,mSelectMonth,it + 1,lunar,festival,-1))
        }
        calendarAdapter = TimePeriodCalendarAdapter(mSelectYear,mSelectMonth,mSelectDay,data,context)
        wgvCalendar.adapter = calendarAdapter
    }


    /**
     * 获取第一天为星期几
     */
    private fun getMonthOneDayWeek(): Int {
        val a: Calendar = Calendar.getInstance()
        a.set(Calendar.YEAR, mSelectYear)
        a.set(Calendar.MONTH, mSelectMonth)
        a.set(Calendar.DATE, 1) //把日期设置为当月第一天
        return a.get(Calendar.DAY_OF_WEEK)
    }

    /**
     * 获取选中的为星期几
     */
    private fun getMonthDayWeek(): Int {
        val a: Calendar = Calendar.getInstance()
        a.set(Calendar.YEAR, mSelectYear)
        a.set(Calendar.MONTH, mSelectMonth)
        a.set(Calendar.DATE, mSelectDay) //把日期设置为当月第一天
        return a.get(Calendar.DAY_OF_WEEK)
    }

    /**
     * 获取第一天为星期几
     */
    private fun getMonthLastDayWeek(): Int {
        val a: Calendar = Calendar.getInstance()
        a.set(Calendar.YEAR, mSelectYear)
        a.set(Calendar.MONTH, mSelectMonth)
        a.set(Calendar.DATE, getMonthMaxDay()) //把日期设置为当月第一天
        return a.get(Calendar.DAY_OF_WEEK)
    }

    /**
     * 获取当月有几天
     */
    private fun getMonthMaxDay(): Int {
        val a: Calendar = Calendar.getInstance()
        a.set(Calendar.YEAR, mSelectYear)
        a.set(Calendar.MONTH, mSelectMonth)
        return a.getActualMaximum(Calendar.DAY_OF_MONTH)
    }

    /**
     * 获取当月有几天
     */
    private fun getMonthMaxDay(year:Int,month:Int): Int {
        val a: Calendar = Calendar.getInstance()
        a.set(Calendar.YEAR, year)
        a.set(Calendar.MONTH, month)
        return a.getActualMaximum(Calendar.DAY_OF_MONTH)
    }
}